﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Timers;

namespace KiDS_Projekat
{
	/// <summary>
	/// Klasa odgovorna za generisanje nove temperature i slanje te temperature ostalim cvorovima
	/// Temperatura se cuva u Kelvinimia, da bi se izbegao negativan predznak
	/// </summary>
	public class TemperatureThreadTimer
	{
		private double _temperature;
		private Thread _thread;
		private System.Timers.Timer _timer;
		private Random random = new Random();
		private Node _myNode;

		public TemperatureThreadTimer(Node myNode)
		{
			_myNode = myNode;
			_temperature = 273.15 + random.Next(30);
			_myNode.CollectTemperature(_myNode.Location, _temperature);
			_timer = new System.Timers.Timer(Properties.Settings.Default.RefreshRate);
			_thread = new Thread(() =>
			{
				_timer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
				_timer.Start();
			});
			_thread.Start();
		}

		/// <summary>
		/// Timerska funkcija, poziva se na refreshRate vreme, koje je definisano u konfiguracionom fileu
		/// </summary>
		/// <param name="source"></param>
		/// <param name="e"></param>
		private void OnTimedEvent(object source, System.Timers.ElapsedEventArgs e)
		{
			int rand = random.Next() % 2;
			double nextDouble = random.NextDouble();
			_temperature += (1 - rand) * nextDouble - rand * nextDouble;
			_temperature = Math.Round(_temperature, 2);
			_myNode.CollectTemperature(_myNode.Location, _temperature);
			
			//pokupi sve temperature za koje zna
			string temperatures = "";
			for (int i = 0; i < _myNode.CollectedTemperatures.Count; i++)
			{
				if (i > 0)
					temperatures += ";";
				temperatures += _myNode.CollectedTemperatures[i].Location + ":" + _myNode.CollectedTemperatures[i].Temperature * 100;
			}
			Program.Terminal.Print("Sending temp: " + temperatures, 1);
			List<Tuple<string, Master>> sheduleRemoval = new List<Tuple<string, Master>>();
			//posalje svim masterima za koje zna
			foreach (var item in _myNode.Masters)
			{
				foreach (var master in item.Value)
				{
					if (master.Address == "0.0.0.0")
						master.Address = "127.0.0.1";
					Client client = new Client(master.Address, master.Port);
					if (!client.Open())
					{
						Program.Terminal.Print("Konekcija ka " + master.Address + ":" + master.Port, 1);
						//ako ne uspe da uspostavi konekciju ka nekom masteru, rasporedi ga za uklanjanje
						sheduleRemoval.Add(Tuple.Create(item.Key, master));
					}
					client.SendMessage(CMD.CMD_PUSH_DATA.ParseInt() + " " + temperatures);
					client.Close();
				}
			}

			//pri uklanjanju salje unregister command
			foreach (var item in sheduleRemoval)
			{
				_myNode.Masters[item.Item1].Remove(item.Item2);
				//bootstrap unregister command
			}
		
		}
	}
}
